简单敲入五个字符“vim .”,就能启动我最喜欢的编辑器。这可不是普通的编辑器,而是NeoVim。如今的NeoVim具备键绑定、语言服务器协议(LSP)、语法高亮、内置错误诊断等多种功能。经过全面定制后,NeoVim仅需数毫秒即可启动,实现近乎即时的文件编辑。即使项目有数千个文件,LSP也能迅速反馈项目的状态,将错误信息即时加载到快速修复菜单中,以便快速定位。只需要几个按键,我就能构建、启动、运行或测试项目。我的计算机甚至能通过AI将自然语言直接转换为代码!更神奇的是,这个AI还能在我编码时实时协作,瞬间生成大量(虽然质量存疑的)代码。这一切听起来令人惊叹 。NeoVim的体验堪称美妙流畅、疾如闪电。然而,NeoVim却被某些开发者视为古董。“老顽固!”1他们用这样的称呼嘲讽使用NeoVim并花时间配置的人。毕竟,像IntelliJ那样全功能的集成环境 唾手可得,甚至它所支持的功能之丰富已经远超我这个NeoVim用户的想象边界!
我之所以讲述这些,是因为我们正身处技术奇迹之中而不自知。遭此非议,不是因为我坚守“过时”的工具,也不是因为开发者间的理念之争——这些早已司空见惯。真正震撼的是:文本编辑这项人类智慧的结晶,当前在我们眼中竟如此稀松平常。自动补全、语法高亮、动态文档,这些曾经是具有石破天惊效果的功能,如今却成了开发者的空气与水。回溯历史,人类用了30年才从机器码跃升至高级编程语言,又等待半个世纪迎来语法高亮,直到20世纪70年代后期才出现跨语言的智能支持。编辑器的进化史,本就是一部浓缩的人类计算文明史。
比起使用古董编辑器,我更痴迷于聆听往昔的故事。那些“真正的程序员”能根据磁鼓存储器的旋转节奏来优化代码,以达到最佳的读取速度。多希望能亲眼见证大师们在打孔卡片上施展魔法!或许这只是一种浪漫的怀旧,但那个时代的每个突破都重塑了世界。在本书中,我有机会与计算历史中那些缔造过重大飞跃的创造者们并肩走过那段时光。我看到查尔斯·巴贝奇(Charles Babbage)用差分机震撼了维多利亚时代的沙龙,机械巨兽发出的叮叮当当的运转声,所产生的东西在当时看来一定是魔法。那种感受恰似今天我们初见大语言模型或Copilot自动生成代码时的震撼。我敢打赌,在那个时候你一定会在晚宴上听到客人惊呼:“机器真的能思考?”我感受到那时的团队昼夜不停工作的压力,以及在二战关键计算中对更强计算能力的迫切需求,这些计算使得原子弹成为可能。他们没有Herman Miller人体工程办公椅,也没有时尚的站立式办公桌;见鬼,他们甚至都没有显示器或键盘!然而,他们取得了不可思议的成果,改变了人类发展的进程。本书是这段计算历史表述中最引人入胜的讲述之一。
如果一个程序员没听说过Uncle Bob的名号,我会非常惊讶。他在我们行业中绝对是多产的。多年来,我只是通过 Twitter以及他在整洁代码和敏捷开发方面的重要贡献才知道Uncle Bob。在我心中,他一直是一种抽象的存在2,直到某天在Twitter上我与他互动后我的心态才发生了变化。通过电子邮件、电话,甚至播客的交流,我看到一个远比教科书更立体的罗伯特·C. 马丁:他务实,在需要时愿意做出让步。在播客节目中,最一致的评论是“他温文尔雅,笑容满面!”这反映了他豁达的性格和丰富充实的生活经历。他是一个真正的软件工程师,也是我们学习的榜样。
我个人已经厌倦了无数关于空格键、编辑器以及面向对象编程与函数式编程的争论,这些争论在X上激烈地展开着。我感兴趣的是,到底是谁创造了这些引发争论的技术。本书连接起过去的岁月和未来的希望,将更有意义的东西呈现给我们,而Uncle Bob就是讲述这个故事的完美人选。
——ThePrimeagen3
1 原文是“ Luddite!”。 Luddite,即卢德主义者,是 19世纪英国的一个激进主义团体,反对工业革命,主张手工劳动和传统手工艺。——译者注
2 原文是“Avatar of AbstractBuilderFactory”。这个表述是对Uncle Bob的幽默化隐喻,结合了软件工程中的两个经典设计模式:Abstract Factory(抽象工厂模式)和Builder(建造者模式)。前者是创建相关对象家族的接口,隐藏具体实现。后者是分步骤构建复杂对象的模式。将两者合成为“AbstractBuilderFactory”这个虚构概念,其隐喻意义在于:强调Uncle Bob作为软件架构大师的形象,暗示其著作中强调抽象设计和模式应用的特点。——译者注
3 ThePrimeagen是YouTube频道号,主持人Michael Paulson是科技界颇具影响力的人物,以快速使用 vim编辑器、编程直播、技术视频等内容而在Twitch和YouTube上闻名。——译者注
自 序
我即将为你讲述这一切是如何开始的。这是一个曲折的故事,讲述了那些非凡人物的生活与挑战,他们所处的非凡时代,以及他们所掌握的非凡机器。
但在我们深入探索这些曲折的历程之前,或许先来一个小小的预览是合适的——只是为了激发你的兴趣。
需要可能是发明之母,但没有什么比战争更能激发需求。我们这个行业的推动力正是由战争的剧变——尤其是第二次世界大战——所创造的。
在20世纪40年代,战争技术已经超越了我们的计算能力。仅靠人类操作的台式计算器根本无法满足来自战争各领域的计算需求。
问题在于,为了近似计算从火炮发射的炮弹到目标的路径,需要进行大量的加减乘除运算。这类问题并不能通过d=rt或s=1/2at2这样的简单公式来解决。这些问题要求将时间和距离分解成成千上万个小段,并逐段模拟和近似弹道。这种模拟需要大量计算。
在过去几个世纪里,所有这些计算都是由成群的人用笔和纸完成的。直到20世纪,他们才得到了加法机来协助这项任务。完成这些计算以及组织执行计算的团队是一项艰巨的任务。1计算本身可能需要这些团队花费数周甚至数月的时间。
在19世纪,人们曾梦想过得到能够完成这些壮举的机器。甚至创造过一些功能比较简单的原型机。但它们只是玩具和奇观,是精英们在晚宴上展示的花哨装置。很少有人认为它们是值得使用的工具;考虑到它们不菲的成本使一切变得更遥远。
但第二次世界大战改变了这一切。需求迫切,成本变得无关紧要。于是,那些早期的梦想变成了现实,庞大的计算机器被建造出来。
那些编写代码和操作机器的人是计算领域的先驱。起初,他们被迫在最原始的条件下工作。编程指令实际上是通过在长长的纸带上逐一打孔来完成的,机器会读取并执行这些纸带。这种编程方式极其烦琐,且完全不容错。此外,这种程序的执行可能需要数周时间,其间需要详细监控和持续干预。例如,执行程序中的循环时,需要通过手动重新定位纸带以进行每次迭代,并手动检查机器状态以确定循环是否应终止。
随着时间的推移,机电机器被电子真空管机器所取代,后者将数据存储在通过长长的水银管传播的声波中。打孔卡片最终被存储程序取代。这些新技术由早期的先驱们推动,并促进了进一步的创新。
20世纪 50年代初的第一个编译器不过是带有特殊关键字的汇编器,用于加载和调用预先编写的子程序——有时来自纸带或磁带。后来的编译器尝试了表达式和数据类型,但仍然原始且缓慢。到了20世纪50年代末,约翰·巴克斯(John Backus)的 FORTRAN和格蕾丝·霍珀(Grace Hopper)的COBOL引入一种全新的思维方式。程序员之前手工编写的二进制代码从此可由能够读取和解析抽象文本的计算机程序生成。
在20世纪60年代初,迪杰斯特拉(Dijkstra)的ALGOL提升了抽象层次。几年后,达尔(Dahl)和尼加德(Nygaard)的SIMULA 67再次将抽象层次提升到新高度。
结构化编程和面向对象编程就是从这些起点中诞生的。
同时,约翰·凯梅尼(John Kemeny)和他的团队在1964年通过创建BASIC和分时系统将计算带给了普通人。BASIC是一种几乎任何人都能理解和使用的语言。分时系统允许许多人方便地同时使用一台昂贵的计算机。
此后,肯·汤普森(Ken Thompson)和丹尼斯·里奇(Dennis Ritchie)在60年代末和 70年代初,通过创建C语言和UNIX,开辟了软件开发的世界。从那以后,软件开发领域开始了飞速发展。
20世纪60年代的大型机革命之后是70年代的小型机革命和80年代的微型计算机革命。个人电脑在80年代席卷了整个行业,随后迅速迎来了面向对象革命、互联网革命和敏捷革命。软件开始主导一切。
9·11事件和互联网泡沫破裂使我们停滞了几年,但随后迎来了Ruby/Rails革命和移动革命。然后,互联网变得无处不在。社交网络蓬勃发展,然后衰落,而人工智能则崛起,雷霆万钧般涌来。
这让我们来到了现在,思考未来。所有这些,以及更多,都将在本书的页面上进行讨论。所以,如果你准备好了,那就系好安全带——因为这将是一次穿梭于时空的绮丽又狂野的旅程。
1 要亲眼目睹这样的任务是如何进行的,推荐参加2024年圆周率日庆祝活动。在一周内,一个由数百人组成的非常协调的团队手工计算了100多位数字。“一个世纪以来最大的手工计算![圆周率日2024]”由Stand-up Maths于2024年3月13日发布在YouTube上。
故事时间线
本书故事所描述的人物和事件都展示在这条时间线上。当你阅读故事中的相关事件时,可从这里定位,了解它们发生的背景。例如,你可能会发现一件有趣的事,如 FORTRAN1和Sputnik2在时间上是巧合的,两者在无意中邂逅;或者肯·汤普森(Ken Thompson)在迪杰斯特拉(Dijkstra)提出GOTO语句有害之前就加入了贝尔实验室(Bell Labs)。
1 世界上第一门高级编程语言,IBM首次发布于1957年。详见书中章节。——译者注
2 世界上第一颗人造卫星,于1957年10月4日成功发射。详见书中章节。——译者注